package com.markchu.modules.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.markchu.common.data.PageSort;
import com.markchu.common.enums.StatusEnum;
import com.markchu.modules.system.domain.Chats;
import com.markchu.modules.system.domain.User;
import com.markchu.modules.system.repository.UserRepository;
import com.markchu.modules.system.service.ChatsService;
import com.markchu.modules.system.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.markchu.modules.system.repository.ChatsRepository;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;

/**
 * @author mark_chu
 * @date 2023/12/08
 */
@Service
public class ChatsServiceImpl implements ChatsService {

    @Autowired
    private ChatsRepository chatsRepository;

    @Autowired
    private UserRepository userRepository;

    /**
     * 根据ID查询数据
     * @param id 主键ID
     */
    @Override
    public Chats getById(Long id) {
        return chatsRepository.findById(id).orElse(null);
    }

    /**
     * 获取分页列表数据
     * @param example 查询实例
     * @return 返回分页数据
     */
    @Override
    public Page<Chats> getPageList(Example<Chats> example) {
        // 创建分页对象
        PageRequest page = PageSort.pageRequest("createDate",Sort.Direction.ASC);
        return chatsRepository.findAll(example, page);
    }
    @Override
    public List<Chats> findPageList(Chats chats) {
        PageRequest page = PageSort.pageRequest("createDate",Sort.Direction.ASC);
        Long offset = page.getOffset();
        Integer pageSize = page.getPageSize();
        return chatsRepository.getAllDatas(chats.getFromAndTo(), DateUtil.formatDateTime(chats.getCreateDate()), offset,pageSize);
    }
    /**
     * 保存数据
     * @param chats 实体对象
     */
    @Override
    public Chats save(Chats chats) {
        return chatsRepository.save(chats);
    }

    /**
     * 状态(启用，冻结，删除)/批量状态处理
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateStatus(StatusEnum statusEnum, List<Long> idList) {
        return chatsRepository.updateStatus(statusEnum.getCode(), idList) > 0;
    }

    @Override
    public List<UserVo> findAllChats(Chats chats) {
            List<Long> userFromIds = chatsRepository.findAllFromUserIds(chats.getFromUserId());
            List<Long> userToIds = chatsRepository.findAllToUserIds(chats.getToUserId());
            List<Long> allUserIds = new ArrayList<>();
            allUserIds.addAll(userFromIds);
            allUserIds.addAll(userToIds);
            LinkedHashSet<Long> set = new LinkedHashSet<>(allUserIds);

            List<User> allUsers = userRepository.findAllById(set);
            List<UserVo> resultList = BeanUtil.copyToList(allUsers, UserVo.class);
            return resultList;
    }

    @Override
    public Page<Chats> getPageList(Chats chats) {
        // 创建分页对象
        PageRequest page = PageSort.pageRequest("createDate",Sort.Direction.DESC);
        // 使用Specification复杂查询
        return chatsRepository.findAll(new Specification<Chats>(){
            @Override
            public Predicate toPredicate(Root<Chats> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> preList = new ArrayList<>();
                List<Predicate> fromUserIdOrtoUserId = new ArrayList<>();
                if(chats.getFromUserId() != null){
                    fromUserIdOrtoUserId.add(cb.equal(root.get("fromUserId").as(Long.class), chats.getFromUserId()));
                }
                if(chats.getToUserId() != null){
                    fromUserIdOrtoUserId.add(cb.equal(root.get("toUserId").as(Long.class), chats.getToUserId()));
                }
                // 数据状态
                preList.add(cb.or(fromUserIdOrtoUserId.toArray(new Predicate[0])));
                preList.add(cb.equal(root.get("status").as(Byte.class), StatusEnum.OK.getCode()));

                Predicate[] pres = new Predicate[preList.size()];
                return query.where(preList.toArray(pres)).getRestriction();
            }
        }, page);
    }


}